﻿using System;
using System.Net;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

//自定义命名空间
using DreamCube.Framework.Utilities.ActiveX;
using RemotingFramework = DreamCube.Framework.Utilities.Remoting;
using BGN.Common.Remoting;

namespace BGN.ActiveX.SInfo
{
    /// <summary>
    /// 将事件接收接口连接到托管类
    /// </summary>
#if publish
    [ComVisible(true), Guid("8d7d8518-ca58-4863-b94d-3c616fda7b35")]
#else
    [ComVisible(true), Guid("12222159-3F44-4D8A-B300-6B9A054FA4D6")]
#endif
    [ComDefaultInterface(typeof(ISisenMESS_Msg)),
    ComSourceInterfaces(typeof(ISisenMESS_Msg_Event)),
    ClassInterface(ClassInterfaceType.None)]
    public class SisenMESS_Msg : BasicActiveX, ISisenMESS_Msg
    {
        //必须自定义委托才可以触发事件
        public delegate void OnSystemComandHandler(String command, String[] args);
        public delegate void OnSystemComandHandler2(String command);
        public delegate void OnTestEventHandler(String msg);

        public event OnSystemComandHandler OnSystemComand;
        public event OnSystemComandHandler2 OnSystemComand2;
        public event OnTestEventHandler OnTestEvent;

        //标志是否已经连接上服务器
        private Boolean hasConnected = false;

        /// <summary>
        /// 提醒服务器，登陆成功了（需要采用异步执行，预防客户端卡死了）
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="connectPort">ActiveX发送消息到布谷鸟客户端的接口</param>
        /// <param name="msgPort">ActiveX接收布谷鸟客户端发送过来的接口</param>
        public void ConnectServer(String ip, Int32 connectPort, Int32 msgPort)
        {
            try
            {
                //先在ActiveX端初始化服务器端的环境
                InitialServer(msgPort);
                ThreadPool.QueueUserWorkItem(new WaitCallback(DoConnectServer), new Object[] { ip, connectPort });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 初始化客户端状态
        /// （由于ActiveX客户端无法接受Remoting服务器端的触发的事件，原因不明，所以ActiveX必须充当服务器端，所以此方法不断主动通知布谷鸟客户端来连接）
        /// </summary>
        void DoConnectServer(Object values)
        {
            try
            {
                Object[] paramValues = values as Object[];
                if (paramValues != null && paramValues.Length == 2)
                {
                    String ip = paramValues[0].ToString();
                    Int32 port = Convert.ToInt32(paramValues[1]);
                    IPAddress address;
                    if (IPAddress.TryParse(ip, out address))
                    {
                        //初始化remoting信道
                        RemotingFramework.Client.Instance.InitialClient();
                        //创建连接对象，告诉服务器端已连接
                        //不断去重新连接布谷鸟客户端
                        while (true)
                        {
                            try
                            {
                                SystemConnection connection = RemotingFramework.Server.Instance.CreateRemotingObj<SystemConnection>(port, "tcp", ip, true);
                                connection.Connect();
                                hasConnected = true;
                            }
                            catch (Exception ex)
                            {
                                hasConnected = false;
                            }
                            //每两秒去连接一次
                            System.Threading.Thread.Sleep(5000);
                        }
                    }
                }
            }
            catch (Exception)
            { }
        }

        SystemCommand command = null;
        private static Int32 hasInitialServer = 0;

        /// <summary>
        /// 初始化服务器的状态
        /// </summary>
        void InitialServer(Int32 msgPort)
        {
            if (Interlocked.CompareExchange(ref hasInitialServer, 1, 0) == 0)
            {
                //初始化remoting信道
                RemotingFramework.Server.Instance.InitialServer(msgPort, "ActiveXRemotingPort");
                command = new SystemCommand();
                command.SystemCommandFromServer += new Action<String>(command_SystemCommandFromServer);
                RemotingFramework.Server.Instance.RegisterRemotingObjByInstance(command, null, System.Runtime.Remoting.WellKnownObjectMode.Singleton);
            }
        }

        /// <summary>
        /// 当接收到命令时提示
        /// </summary>
        /// <param name="obj"></param>
        void command_SystemCommandFromServer(String obj)
        {
            OnSystemComand2(obj);
        }

        void wrapper_TargetEvent(String t1, String[] t2)
        {
            try
            {
                OnSystemComand(t1, t2);
            }
            catch (Exception)
            { }
        }

        public void Test()
        {
            MessageBox.Show("Hello World");
        }

        public void TestEvent(String inputValue)
        {
            OnTestEvent(inputValue);
        }
    }
}
